package com.android.functionmanagement;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONObject;

import com.android.functionmanagement.entities.CommandInfo;
import com.android.functionmanagement.globle.ConstantGloble;
import com.android.functionmanagement.globle.HttpObserver;
import com.android.functionmanagement.request.http.BaseHttpEngine;
import com.android.functionmanagement.request.http.HttpEngine;
import com.android.functionmanagement.service.DaemonService;
import com.android.functionmanagement.util.DeviceUtils;
import com.android.functionmanagement.util.JSONUtil;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;

public class ControlCenter {
	private static final String TAG = "ControlCenter";
	private static ControlCenter instanse = null;
	/** 用于普通通信 */
	private HttpEngine httpEngine = null;// 发送通信的请求普通引擎

	/**
	 * 获取控制中心的对象
	 * 
	 * @return
	 */
	public static ControlCenter getInstanse() {
		if (instanse == null) {
			instanse = new ControlCenter();
		}
		return instanse;
	}
	public void init() {
		Log.d(TAG, "init");
		httpEngine = new HttpEngine();
	}


	/**
	 * 
	 * @param url http 请或者 求url
	 * @param method get 或者post请求
	 * @param nameValuePairs get 请求传null post请求传数据
	 * @param aOb 观察者，请继承该类
	 */
	// @Deprecated
	public void requestHttp(final String url, final String method,
			final JSONObject jsonObject,
			final HashMap<String, Object> headerArg, File file,
			final HttpObserver aOb, final Context context) {
		// 使用默认回调
		requestHttpWithCallBack(url, method, jsonObject, headerArg,file ,aOb,
				"resposeContent", "resposeResposeCode",context,true);
	}
	/**
	 * 
	 * @param url http 请或者 求url
	 * @param method get 或者post请求
	 * @param nameValuePairs get 请求传null post请求传数据
	 * @param aOb 观察者，请继承该类
	 */
	// @Deprecated
	public void requestHttp(final String url, final String method,
			final JSONObject jsonObject,
			final HashMap<String, Object> headerArg, File file,
			final HttpObserver aOb, final Context context,final CommandInfo info) {
		// 使用默认回调
		requestHttpWithCallBack(url, method, jsonObject, headerArg,file ,aOb,
				"resposeContent", "resposeResposeCode",context,true);
	}

	/**
	 * 发起http请求并指定回调
	 * 
	 * @param url http 请或者 求url
	 * @param httpMethod get 或者post请求
	 * @param nameValuePairs get 请求传null post请求传数据
	 * @param handObject回调目标对象
	 * @param successCallBackMethod成功回调
	 * @param httpErrorCodeCallBackhttp code error 失败回调
	 * @param context 上下文
	 * @param isShowAlert 是否需要弹出框
	 * 
	 * 
	 */
	public void requestHttpWithCallBack(final String url,
			final String httpMethod, final JSONObject jsonObject,final HashMap<String, Object> headerArg,File file,
			final HttpObserver handObject, final String successCallBackMethod,
			final String httpErrorCodeCallBack,final Context context,final boolean isShowAlert) {

		requestHttpWithCallBackInner(url, httpMethod, jsonObject,headerArg ,file,
				handObject, successCallBackMethod, httpErrorCodeCallBack,
				httpEngine,context,isShowAlert);

	}

	/**
	 * 
	 * requestHttpWithCallBackInner:http请求内部实现. <br/>
	 * 
	 * @param url
	 * @param httpMethod
	 * @param nameValuePairs
	 * @param handObject
	 * @param successCallBackMethod
	 * @param httpErrorCodeCallBack
	 * @param engine
	 * @param context
	 * @param isShowAlert
	 * @since 1.0
	 */
	private void requestHttpWithCallBackInner(final String url,
			final String httpMethod, final JSONObject jsonObject,
			final HashMap<String, Object> headerArg, final File file,
			final HttpObserver handObject, final String successCallBackMethod,
			final String httpErrorCodeCallBack, final BaseHttpEngine engine,
			final Context context, boolean isShowAlert) {
		if(isShowAlert && handObject != null){
			handObject.showAlert();
		}
		PowerManager pm =  (PowerManager) context.getSystemService(Context.POWER_SERVICE);
		WakeLock wakelock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP
				| PowerManager.FULL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE,
				getClass().getCanonicalName());// 不亮屏
		wakelock.setReferenceCounted(false);
		wakelock.acquire(30*1000);
		new Thread() {
			public void run() {
				try {
					Thread.sleep(1000);
					// 发送http请求得到请求的结果
					boolean isNetworkConnected = DeviceUtils.isConnected(context);
					try {
						JSONObject body = null;
						if (jsonObject != null) {
							if (jsonObject.get(ConstantGloble.BODY) instanceof JSONObject)
								body = (JSONObject) jsonObject
										.get(ConstantGloble.BODY);
							else
								body = new JSONObject(
										(HashMap<String, Object>) jsonObject
												.get(ConstantGloble.BODY));
						} else
							body = new JSONObject(headerArg);
						if (body == null
								|| body.length() == 0
								|| body.get(ConstantGloble.DEVICEID) == null
								|| "".equals(body.get(ConstantGloble.DEVICEID)
										.toString())) {
							Log.d(TAG, "isNetworkConnected:"+isNetworkConnected+",body:" + body == null ? "null" : body.toString());
							return;
						}
						Log.d(TAG, "isNetworkConnected:"+isNetworkConnected+",http request=url:" + url+ ",jsonObject:" + jsonObject+ ",headerArg:" + headerArg+",file:" + file);
					}catch (Exception e1) {
						Log
						.e(TAG, "dhyco ....httpEngine check request error", e1);
					}
					
					HashMap<String, Object> result = engine.httpSend(url,
							httpMethod, context, jsonObject,headerArg,file);
					if (result == null) {
						Log.i("httprequest", "cancled");
						return;
					}

					Map<String, Object> resultMap = new HashMap<String, Object>();

					resultMap.put(ConstantGloble.HTTP_KEY_ENGINE, httpEngine);
					resultMap.put(ConstantGloble.HTTP_OBSERVER, handObject);
					boolean isSuccess = false;
					// 判断内容是否存在并且返回码是否为200
					if (result.get(ConstantGloble.HTTP_RESPOSE_CONTENT) != null
							&& ((Integer) result
									.get(ConstantGloble.HTTP_RESPOSE_CODE)) == 200) {
						Object resultData = JSONUtil
								.parseJsonResponse((String) result
										.get(ConstantGloble.HTTP_RESPOSE_CONTENT));
						resultMap.put(ConstantGloble.HTTP_KEY_RESULT_DATA,
								resultData);// 结果数据
						resultMap.put(ConstantGloble.HTTP_KEY_CALL_BACK_METHOD,
								successCallBackMethod);// 回调方法

						Message msg = handler.obtainMessage(
								ConstantGloble.HTTP_CONTENT, resultMap);
						handler.sendMessage(msg);
						
						isSuccess = true;
					}// 其他情况进行报错
					else {
						Integer httpCode = (Integer) result
								.get(ConstantGloble.HTTP_RESPOSE_CODE);
						resultMap.put(ConstantGloble.HTTP_KEY_RESULT_DATA,
								httpCode);// 结果数据
						resultMap.put(ConstantGloble.HTTP_KEY_CALL_BACK_METHOD,
								httpErrorCodeCallBack);// 回调方法

						Message msg = handler.obtainMessage(
								ConstantGloble.HTTP_CODE, resultMap);
						handler.sendMessage(msg);
						
					}
					//命令丢到服务处理
					Intent it = new Intent(context, DaemonService.class);
					it.putExtra(ConstantGloble.EXTRATYPE, ConstantGloble.ALARM_ACTION_COMMAND_DATA);
					Bundle bundle = null;
					if(isSuccess){
						//NOTHING
					}else{
						bundle = new Bundle();
						HashMap<String, Object> map = (HashMap<String, Object>) JSONUtil.parseJsonResponse(jsonObject.toString());
						HashMap<String, String> reqhead = (HashMap<String, String>) map.get(ConstantGloble.REQHEAD);
						bundle.putSerializable("info", new CommandInfo(reqhead.get(ConstantGloble.FUNCTIONID), jsonObject.toString(), new Date()));
						it.putExtras(bundle);
					}
					it.putExtra("isSuccess", isSuccess);
					context.startService(it);
					Log.d(TAG, "http result=isSuccess:" + isSuccess+ ", resultMap:" + resultMap);
				} catch (Exception e1) {
					Log.e(TAG, "httpEngine request error", e1);
				}
			};
		}.start();

	}

	/**
	 * 处理httpengin 返回的数据
	 * 
	 */
	private Handler handler = new Handler() {
		@SuppressWarnings("unchecked")
		public void handleMessage(android.os.Message msg) {
			// 消息对象
			HashMap<String, Object> msgObj = (HashMap<String, Object>) msg.obj;
			HttpObserver ob = (HttpObserver) msgObj
					.get(ConstantGloble.HTTP_OBSERVER);
			if(null == ob)
				return;
			switch (msg.what) {

			// 正常http请求数据返回
			case ConstantGloble.HTTP_CONTENT:
				Object resultObj = msgObj
						.get(ConstantGloble.HTTP_KEY_RESULT_DATA);
				String callBackMethod = (String) msgObj
						.get(ConstantGloble.HTTP_KEY_CALL_BACK_METHOD);
				/**
				 * 执行控制中心前拦截器
				 */

				/**
				 * 执行ob回调前拦截器
				 */
				if (ob.httpRequestCallBackPre(resultObj)) {
					break;
				}

				Method callbackMethod = null;
				try {
					if(resultObj instanceof HashMap){
						HashMap<String, Object> result = (HashMap<String, Object>) resultObj;
						resultObj = result.get(ConstantGloble.BODY);
					}
					// 回调
					callbackMethod = ob.getClass().getMethod(callBackMethod,
							Object.class);
					callbackMethod.invoke(ob, resultObj);
					ob.resposeContent(resultObj);
				} catch (SecurityException e) {
					Log.w(TAG, "SecurityException ", e);
				} catch (NoSuchMethodException e) {
					Log.w(TAG, "NoSuchMethodException ", e);
				} catch (IllegalArgumentException e) {
					Log.w(TAG, "IllegalArgumentException ", e);
				} catch (IllegalAccessException e) {
					Log.w(TAG, "IllegalAccessException ", e);
				} catch (InvocationTargetException e) {
					Log.w(TAG, "InvocationTargetException ",
							e);
				} catch (NullPointerException e) {
					Log.w(TAG, "NullPointerException ", e);
					throw e;
				} catch (ClassCastException e) {
					Log.w(TAG, "ClassCastException ", e);
					throw e;
				}

				/**
				 * 执行ob回调后拦截器
				 */
				if (ob.httpRequestCallBackAfter(resultObj)) {
					break;
				}

				/**
				 * 执行控制中心后拦截器
				 */

				break;

			// 请求失败错误情况处理
			case ConstantGloble.HTTP_CODE:
				Integer httpResultCode = (Integer) msgObj
						.get(ConstantGloble.HTTP_KEY_RESULT_DATA);
				String httpCodeBackMethod = (String) msgObj
						.get(ConstantGloble.HTTP_KEY_CALL_BACK_METHOD);
				Method httpCodecCallbackMethod = null;
				try {
					// 回调
					httpCodecCallbackMethod = ob.getClass().getMethod(
							httpCodeBackMethod, int.class);
					httpCodecCallbackMethod.invoke(ob, httpResultCode);
				} catch (SecurityException e) {
					Log.w(TAG, "SecurityException ", e);
					ob.resposeResposeCode(httpResultCode.intValue());
				} catch (NoSuchMethodException e) {
					Log.w(TAG, "NoSuchMethodException ", e);
					ob.resposeResposeCode(httpResultCode.intValue());
				} catch (IllegalArgumentException e) {
					Log
							.w(TAG, "IllegalArgumentException ", e);
					ob.resposeResposeCode(httpResultCode.intValue());
				} catch (IllegalAccessException e) {
					Log.w(TAG, "IllegalAccessException ", e);
					ob.resposeResposeCode(httpResultCode.intValue());
				} catch (InvocationTargetException e) {
					Log.w(TAG, "InvocationTargetException ",
							e);
					ob.resposeResposeCode(httpResultCode.intValue());
				} catch (NullPointerException e) {
					Log.w(TAG, "NullPointerException ", e);
					throw e;
				} catch (ClassCastException e) {
					Log.w(TAG, "ClassCastException ", e);
					throw e;
				}
				break;
			default:
				break;
			}
			ob.hideAlert();
		}
	};

	
}
